package com.project.frame.common.utils.http;

import cn.hutool.core.util.StrUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.nio.charset.Charset;

/**
 * @Title: RequestWrapper
 */
public class RequestWrapper extends HttpServletRequestWrapper {

    private static Logger logger = LoggerFactory.getLogger(RequestWrapper.class);

    private final String body;

    public RequestWrapper(HttpServletRequest request) {
        super(request);
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader bufferedReader = null;
        InputStream inputStream = null;
        try {
            inputStream = request.getInputStream();
            if (inputStream != null) {
                String charsetName = "UTF-8";
                String contentType = request.getHeader("Content-Type");
                if (!(StrUtil.isBlank(contentType) || "undefined".equals(contentType))) {
                    contentType = contentType.replaceAll(" ", "");
                    // application/json; charset=utf-8
                    String[] contentTypeArr = contentType.split(";");
                    for (String str : contentTypeArr) {
                        if (str.startsWith("charset=")) {
                            charsetName = str.substring(8);
                            break;
                        }
                    }
                }
                logger.info("defaultCharsetName: {}", Charset.defaultCharset().name());
                logger.info("charsetName: {}", charsetName);
                if (StrUtil.isBlank(charsetName) || "undefined".equals(charsetName)) {
                    bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                } else {
                    bufferedReader = new BufferedReader(new InputStreamReader(inputStream, charsetName));
                }

                String str = null;
                while ((str = bufferedReader.readLine()) != null) {
                    stringBuilder.append(str);
                }
            } else {
                stringBuilder.append("");
            }
        } catch (IOException ex) {
            logger.error("body读取失败");
            logger.error(ex.getMessage());
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        body = stringBuilder.toString();
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
        ServletInputStream servletInputStream = new ServletInputStream() {
            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener readListener) {
            }

            @Override
            public int read() throws IOException {
                return byteArrayInputStream.read();
            }
        };
        return servletInputStream;

    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(this.getInputStream()));
    }

    public String getBody() {
        return this.body;
    }

}
